package deviceManage

/*
    #cgo CFLAGS: -I../
    #cgo LDFLAGS: -L../ -ldecd -lm
	#include "compute.h"
	#include "device.h"
	#include "key.h"
	#include "manager.h"
	#include "xdma.h"
    #include <stdlib.h>
*/
import "C"
import (
	"errors"
	"fmt"
	"unsafe"
)

// NFHE_DECD_OpenDevice 打开设备
func NFHE_DECD_OpenDevice() error {
	var err error // 出错返回值
	rv := C.NFHE_OpenDevice()
	if rv != 0 {
		cw := fmt.Sprintf("%x", rv)
		err = errors.New("出错信息:打开设备时出错！错误号：" + cw)
	} else {
		return nil
	}
	return err
}

// NFHE_DECD_CloseDevice 关闭设备
func NFHE_DECD_CloseDevice() error {
	var err error // 出错返回值
	rv := C.NFHE_CloseDevice()
	if rv != 0 {
		cw := fmt.Sprintf("%x", rv)
		err = errors.New("出错信息:关闭设备时出错！错误号：" + cw)
	} else {
		return nil
	}
	return err
}

// DECD_Restore_FactorySetting 恢复出厂状态
func DECD_Restore_FactorySetting(ls_password string, ls_password_len int) error {
	var err error                  // 出错返回值
	var ll_len int                 //口令长度变量
	ll_len = int(len(ls_password)) // 强制类型转换
	if ll_len == ls_password_len { // 判断口令长度是否等于8
		cs := C.CString(ls_password) // 用CGO语言的字符串功能转换
		var cs1 = (*C.uchar)(unsafe.Pointer(cs))
		defer C.free(unsafe.Pointer(cs)) // 动态回收内存空间
		pLen := C.uint(ls_password_len)  // 用CGO语言的强制类型转换

		primaryFactoryInformation := C.CString("HUST华中科技大学")
		var primaryFactoryInformation1 = (*C.char)(unsafe.Pointer(primaryFactoryInformation))
		defer C.free(unsafe.Pointer(primaryFactoryInformation)) // 动态回收内存空间

		primaryFactoryDate := C.CString("2024.01.16")
		var primaryFactoryDate1 = (*C.char)(unsafe.Pointer(primaryFactoryDate))
		defer C.free(unsafe.Pointer(primaryFactoryDate)) // 动态回收内存空间

		rv := C.FHEKmg_Restore_FactorySetting(cs1, pLen, primaryFactoryInformation1, primaryFactoryDate1) // 初始化设备，并创建设备主密钥、密钥加密密钥
		if rv != 0 {
			cw := fmt.Sprintf("%x", rv)
			err = errors.New("出错信息:恢复出厂设置时出错！错误号：" + cw)
		} else {
			return nil
		}
	} else {
		err = errors.New("出错信息:设备密钥长度等于16。")
	}
	return err

	//var err error // 出错返回值
	//rv := C.FHEDbg_Restore_FactorySetting()
	//if rv != 0 {
	//	cw := fmt.Sprintf("%x", rv)
	//	err = errors.New("出错信息:恢复出厂状态时出错！错误号：" + cw)
	//} else {
	//	return nil
	//}
	//return err
}

// DECD_Kmg_Init_Device 初始化设备功能
func DECD_Kmg_Init_Device(ls_password string, ls_password_len int) error {
	var err error                  // 出错返回值
	var ll_len int                 //口令长度变量
	ll_len = int(len(ls_password)) // 强制类型转换
	if ll_len == ls_password_len { // 判断口令长度是否等于16
		cs := C.CString(ls_password) // 用CGO语言的字符串功能转换
		var cs1 = (*C.uchar)(unsafe.Pointer(cs))
		defer C.free(unsafe.Pointer(cs))      // 动态回收内存空间
		pLen := C.uint(ls_password_len)       // 用CGO语言的强制类型转换
		rv := C.FHEKmg_Init_Device(cs1, pLen) // 初始化设备，并创建设备主密钥、密钥加密密钥
		if rv != 0 {
			cw := fmt.Sprintf("%x", rv)
			err = errors.New("出错信息:初始化设备时出错！错误号：" + cw)
		} else {
			return nil
		}
	} else {
		err = errors.New("出错信息:设备密钥长度等于16。")
	}
	return err
}

//// DECD_Kmg_Update_KeyMngerPassword 修改口令
//func DECD_Kmg_Update_KeyMngerPassword(OldPassword string, OldPassword_len uint, NewPassword string, NewPassword_len uint) error {
//	var err error // 出错返回值
//	cs_old := C.CString(OldPassword)
//	defer C.free(unsafe.Pointer(cs_old))
//	pLen_old := C.uint(OldPassword_len)
//	cs_new := C.CString(NewPassword)
//	defer C.free(unsafe.Pointer(cs_new))
//	pLen_new := C.uint(NewPassword_len)
//	rv := C.DECD_Kmg_Update_KeyMngerPassword(cs_old, pLen_old, cs_new, pLen_new)
//	if rv != 0 {
//		cw := fmt.Sprintf("%x", rv)
//		err = errors.New("出错信息:修改口令时出错！错误号：" + cw)
//	} else {
//		return nil
//	}
//	return err
//}

// DECD_GetDeviceInfo 提取设备版本信息
func DECD_GetDeviceInfo(ls_password string, ls_password_len int) (string, string, string, string, string, string, error) {
	var err error // 出错返回值
	var ret1, ret2, ret3, ret4, ret5, ret6 string
	var ll_len int                 //口令长度变量
	ll_len = int(len(ls_password)) // 强制类型转换
	if ll_len == ls_password_len { // 判断口令长度是否等于16
		PasswordCs := C.CString(ls_password) // 用CGO语言的字符串功能转换
		var PasswordCs1 = (*C.uchar)(unsafe.Pointer(PasswordCs))
		defer C.free(unsafe.Pointer(PasswordCs)) // 动态回收内存空间
		pLen := C.uint(ls_password_len)          // 用CGO语言的强制类型转换

		DeviceName := "                "
		DeviceNameCs := C.CString(DeviceName)
		var DeviceNameCs1 = (*C.char)(unsafe.Pointer(PasswordCs))
		defer C.free(unsafe.Pointer(DeviceNameCs))

		DeviceSerial := "                "
		DeviceSerialCs := C.CString(DeviceSerial)
		var DeviceSerialCs1 = (*C.char)(unsafe.Pointer(DeviceSerialCs))
		defer C.free(unsafe.Pointer(DeviceSerialCs))

		HardwareVersion := "      "
		HardwareVersionCs := C.CString(HardwareVersion)
		var HardwareVersionCs1 = (*C.char)(unsafe.Pointer(HardwareVersionCs))
		defer C.free(unsafe.Pointer(HardwareVersionCs))

		SoftwareVersion := "      "
		SoftwareVersionCs := C.CString(SoftwareVersion)
		var SoftwareVersionCs1 = (*C.char)(unsafe.Pointer(SoftwareVersionCs))
		defer C.free(unsafe.Pointer(SoftwareVersionCs))

		PrimaryFactoryInformation := "                                         "
		PrimaryFactoryInformationCs := C.CString(PrimaryFactoryInformation)
		var PrimaryFactoryInformationCs1 = (*C.char)(unsafe.Pointer(PrimaryFactoryInformationCs))
		defer C.free(unsafe.Pointer(PrimaryFactoryInformationCs))

		PrimaryFactoryDate := "                     "
		PrimaryFactoryDateCs := C.CString(PrimaryFactoryDate)
		var PrimaryFactoryDateCs1 = (*C.char)(unsafe.Pointer(PrimaryFactoryDateCs))
		defer C.free(unsafe.Pointer(PrimaryFactoryDateCs))

		rv := C.FHEKmg_Get_DeviceInfo(PasswordCs1, pLen, DeviceNameCs1, DeviceSerialCs1, HardwareVersionCs1, SoftwareVersionCs1, PrimaryFactoryInformationCs1, PrimaryFactoryDateCs1)
		if rv != 0 {
			cw := fmt.Sprintf("%x", rv)
			err = errors.New("出错信息:提取设备信息时出错！错误号：" + cw)
		}
		ret1 = C.GoString(DeviceNameCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret1)
		ret2 = C.GoString(DeviceSerialCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret2)
		ret3 = C.GoString(HardwareVersionCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret3)
		ret4 = C.GoString(SoftwareVersionCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret4)
		ret5 = C.GoString(PrimaryFactoryInformationCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret5)
		ret6 = C.GoString(PrimaryFactoryDateCs1) // 取出加密的密文值，并且返回
		fmt.Println(ret6)
	} else {
		err = errors.New("出错信息:设备密钥长度等于16。")
	}
	return ret1, ret2, ret3, ret4, ret5, ret6, err
}

//// DECD_Restore_FactorySetting 恢复出厂状态
//func DECD_Restore_FactorySetting() error {
//	var err error // 出错返回值
//	rv := C.DECD_Restore_FactorySetting()
//	if rv != 0 {
//		cw := fmt.Sprintf("%x", rv)
//		err = errors.New("出错信息:恢复出厂状态时出错！错误号：" + cw)
//	} else {
//		return nil
//	}
//	return err
//}

//// DECD_SoftRst 软恢复硬件状态到初始状态
//func DECD_SoftRst() error {
//	var err error // 出错返回值
//	rv := C.DECD_SoftRst()
//	if rv != 0 {
//		cw := fmt.Sprintf("%x", rv)
//		err = errors.New("出错信息:软恢复硬件状态时出错！错误号：" + cw)
//	} else {
//		return nil
//	}
//	return err
//}
